/***************************************************************
*  Copyright (c) 2007 by GroupMe! Team (www.groupme.net)
*  All rights reserved.
*
*  This file is part of the GroupMe! Project. Source code of 
*  this project is closed and redistribution of this code is
*  prohibited. 
*  
*  Contact: http://www.groupme.net
*
*  This copyright notice MUST APPEAR in all copies of the file!
***************************************************************/
package net.groupme.search.google;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import net.groupme.controller.model.SearchResult;
import net.groupme.model.MODEL_CONSTANTS;

import gsearch.Client;
import gsearch.OrderBy;
import gsearch.Response;
import gsearch.Result;

/**
 * 
 * The Google AJAX search engine. 
 * 
 * @author Fabian Abel, <a href="mailto:abel@l3s.de">abel@l3s.de</a>
 * @author last edited by: $Author: fabian $
 * 
 * @version $Revision: 1.1 $ $Date: 2010-02-06 13:16:47 $
 * @version created on Feb 5th 2010
 */
public class AjaxSearch extends Client{
	
	private static final String VIDEO_SEARCH_ENDPOINT = "http://ajax.googleapis.com/ajax/services/search/video";

	/** API key for groupme.org */
//	public static final String API_KEY = "ABQIAAAA5RPFU7pC3SYdVySIw8E8CRQq8Xt-mYsBOIbcWfsGxuEXFVSqvRQNTFrndcwBVojkQN-epJFhrWSYIA";
	/** API key for local tests */
	public static final String API_KEY = "ABQIAAAA5RPFU7pC3SYdVySIw8E8CRQ_hvVlqlFZ2hZG7X4prOwodjA_JBRsEX4Fqo4E8XXTemkM5Y0IjXuLIw";
	
	/**
	 * Returns an Array of {@link SearchResult} instances that suit the given
	 * query which are from the Google Search API
	 * 
	 * @param queryKeyword
	 *            The Keyword which is searched for
	 * @param fileType TODO: (not used currently)
	 *            Only results of this Filetype are searched for
	 * @param numberOfResults TODO: (not used currently)
	 *            The Number of Results which are returned
	 * @return
	 */
	public List<SearchResult> searchGoogle(String queryKeyword,
			String fileType, int numberOfResults) {
		List<SearchResult> resultList = new ArrayList<SearchResult>();
		try{
			List<Result> results = this.searchWeb(queryKeyword);
			if(results != null){
				for(Result res: results){
					SearchResult result = new SearchResult();
					result.setUrl((res.getUnescapedUrl() != null ? res.getUnescapedUrl() : res.getUrl()));
					result.setType(MODEL_CONSTANTS.RESOURCE_TYPE_WEBSITE);
					result.setDescription(cleanString(res.getContent()));
					result.setName( cleanString(res.getTitleNoFormatting()));
					result.setResultID("googleresult" + results.size());
					resultList.add(result);
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		return resultList;
	}
	
	/**
	 * Returns an Array of {@link SearchResult} instances that suit the given
	 * query which are from the Google Video Search API (at the moment we only search for Youtube videos!)
	 * 
	 * @param queryKeyword
	 *            The Keyword which is searched for
	 * @param fileType TODO: (not used currently)
	 *            Only results of this Filetype are searched for
	 * @param numberOfResults TODO: (not used currently)
	 *            The Number of Results which are returned
	 * @return
	 */
	public List<SearchResult> searchGoogleForVideos(String queryKeyword,
			String fileType, int numberOfResults) {
		List<SearchResult> resultList = new ArrayList<SearchResult>();
		try{
			List<Result> results = this.searchVideos(queryKeyword, OrderBy.RELEVANCE);
			if(results != null){
				for(Result res: results){
					SearchResult result = new SearchResult();
					if(res.getPlayUrl() != null){
						result.setUrl(res.getPlayUrl());
					}else{
						result.setUrl((res.getUnescapedUrl() != null ? res.getUnescapedUrl() : res.getUrl()));
					}
					
					if(result.getUrl() != null && result.getUrl().contains("youtube")){
						if(result.getUrl().contains("&autoplay=1")){
							result.setUrl(result.getUrl().replace("autoplay=1", ""));
						}else if(result.getUrl().contains("autoplay=1&")){
							result.setUrl(result.getUrl().replace("autoplay=1&", ""));
						}
						result.setType(MODEL_CONSTANTS.RESOURCE_TYPE_VIDEO);
						result.setDescription(cleanString(res.getContent()));
						result.setName( cleanString(res.getTitleNoFormatting()));
						result.setResultID("googleresult" + results.size());
						resultList.add(result);
					}
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		return resultList;
	} 
	
	/** cleans the <b> and </b> out of the string */
	private String cleanString(String stri) {
		stri = stri.replaceAll("<b>", "");
		return stri.replaceAll("</b>", "");
	}
	/**
	 * Dummy test...
	 * @param args
	 */
	public static void main(String[] args) {
		AjaxSearch search = new AjaxSearch();
		List<SearchResult> results = search.searchGoogle("groupme", null, 10);
		for (SearchResult searchResult : results) {
			System.out.println(searchResult.getName() + "\n"+searchResult.getDescription() + "\n"+searchResult.getUrl()+"\n");
		}
		
		results = search.searchGoogleForVideos("jazz", null, 10);
		for (SearchResult searchResult : results) {
			System.out.println(searchResult.getName() + "\n"+searchResult.getDescription() + "\n"+searchResult.getUrl()+"\n");
		}
		

	}
	/* (non-Javadoc)
	 * @see gsearch.Client#searchBlogs(java.lang.String)
	 */
	@Override
	public List<Result> searchBlogs(String query) {
		return super.searchBlogs(query);
	}
	
	/* (non-Javadoc)
	 * @see gsearch.Client#searchWeb(java.lang.String)
	 */
	@Override
	public List<Result> searchWeb(String query) {
		Map<String, String> params = new LinkedHashMap<String, String>();
		
		params.put("q", query);
		params.put("rsz","large");		
		params.put("key", API_KEY);
		
		Response r = sendWebSearchRequest(params);
		
		return r.getResponseData().getResults();
	}
	
	public List<Result> searchWeb(String query, int page) {
		Map<String, String> params = new LinkedHashMap<String, String>();
		
		params.put("q", query);
		params.put("start",((page * 8) +1)+"");
		params.put("rsz","large");
		
		params.put("key", API_KEY);
		
		Response r = sendWebSearchRequest(params);
		
		return r.getResponseData().getResults();
	}

	/* (non-Javadoc)
	 * @see gsearch.Client#searchVideos(java.lang.String, gsearch.OrderBy)
	 */
	@Override
	public List<Result> searchVideos(String query, OrderBy order) {
		Map<String, String> params = new LinkedHashMap<String, String>();
		if (order == null){
			order = OrderBy.RELEVANCE;
		}
		params.put("q", query);
		params.put("orderBy", order.getValue());
		params.put("rsz","large");
		params.put("key", API_KEY);
		
		Response r = sendSearchRequest(VIDEO_SEARCH_ENDPOINT, params);
		return r.getResponseData().getResults();
	}

}
